#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include "socket_test.h"

#define SERVER_SKT_PATH "/server_socket"
#define SERVER_MODE 1
#define CLIENT_MODE 2

void StartServer()
{
    unlink(SERVER_SKT_PATH);

    int srvSktFd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (srvSktFd == -1) {
        perror("server crate socker");
    }

    struct sockaddr_un srvAddr = { 0 };
    srvAddr.sun_family = AF_UNIX;
    strcpy(srvAddr.sun_path, SERVER_SKT_PATH);
    int  srvLen = sizeof(srvAddr);

    if (bind(srvSktFd, (struct sockaddr*)&srvAddr, srvLen) < 0) {
        perror("server bind err");
        close(srvSktFd);
        return;
    }
    if (listen(srvSktFd, 5) == -1) {
        perror("server listen err");
        close(srvSktFd);
        return;
    }

    int cliSktFd = 0;
    int cliLen = 0;
    struct sockaddr_un cliAddr;
    while (1) {
        char ch;
        printf("server is waiting...\n");
        cliLen = sizeof(cliAddr);
        cliSktFd = accept(srvSktFd, (struct sockaddr*)&cliAddr, &cliLen);
        if (cliSktFd == -1) {
            perror("server accept err");
            close(srvSktFd);
            return;
        }
        printf("get accept_ft:%d from:%s\n", cliSktFd, cliAddr.sun_path);
        read(cliSktFd, &ch, 1);
        printf("get msg from client:%c\n", ch);
        ch++;
        write(cliSktFd, &ch, 1);
        close(cliSktFd);
    }
}

void StartClient()
{
    int sockFd = socket(AF_UNIX, SOCK_STREAM, 0);
    struct sockaddr_un sockAddr;
    // 根据服务器给套接字命名
    sockAddr.sun_family = AF_UNIX;
    strcpy(sockAddr.sun_path, SERVER_SKT_PATH);
    int addrLen = sizeof(sockAddr);

    int result = connect(sockFd, (struct sockaddr*)&sockAddr, addrLen);
    if (result == -1) {
        perror("client connect");
        exit(1);
    }

    char ch = 'A';
    write(sockFd, &ch, 1);
    read(sockFd, &ch, 1);
    printf("char from server is %c\n", ch);
    close(sockFd);
}

void RunSktTest(int argc, char* argv[])
{
    printf("--------------------run Skt begin---------------------\n");
    if (argc < 3) {
        printf("2rd pram means server(1) or client(2)\n");
        return;
    }

    switch (atoi(argv[2])) {
    case SERVER_MODE:
        StartServer();
        break;
    case CLIENT_MODE:
        StartClient();
        break;
    default:
        printf("invalid 2rd parm\n");
        break;
    }

    printf("--------------------run Skt end----------------------\n");
}